package com.edu.exam.entity.curriculum.course;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Comment;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Max;
import jakarta.persistence.Transient;
import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 课程基础信息实体
 * 所属模块：B-01 课程管理模块
 * 对应设计文档：B-01-01-06-数据库设计.md
 *
 * 管理课程的基本信息，包括课程编码、名称、类型、学分、学时等。
 * 不包含业务逻辑代码，仅包含数据字段和JPA注解。
 *
 * @author System
 * @version 1.0.0
 */
@Entity
@Comment("课程基础信息表")
@Table(name = "courses")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Course {

    /**
     * 课程ID，主键
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    /**
     * 课程编码，唯一标识符
     */
    @NotBlank(message = "课程编码不能为空")
    @Column(name = "course_code", nullable = false, unique = true, length = 20)
    private String courseCode;

    /**
     * 课程名称
     */
    @NotBlank(message = "课程名称不能为空")
    @Column(name = "course_name", nullable = false, length = 100)
    private String courseName;

    /**
     * 课程描述，使用大文本字段存储详细描述
     */
    @Column(name = "course_description", columnDefinition = "TEXT")
    private String courseDescription;

    /**
     * 课程类型
     */
    @NotNull(message = "课程类型不能为空")
    @Enumerated(EnumType.STRING)
    @Column(name = "course_type", nullable = false, length = 20)
    private CourseType courseType;

    /**
     * 课程状态
     */
    @NotNull(message = "课程状态不能为空")
    @Enumerated(EnumType.STRING)
    @Column(name = "course_status", nullable = false, length = 20)
    private CourseStatus courseStatus;

    /**
     * 学分，设置精度为小数点后1位，取值范围为0.1-10.0
     */
    @DecimalMin(value = "0.1", message = "学分不能小于0.1")
    @DecimalMax(value = "10.0", message = "学分不能大于10.0")
    @Column(name = "credits", precision = 3, scale = 1)
    private BigDecimal credits;

    /**
     * 理论学时，默认值为0，记录理论教学学时数，设置范围0-1000
     */
    @Min(value = 0, message = "理论学时不能小于0")
    @Max(value = 1000, message = "理论学时不能大于1000")
    @Column(name = "theory_hours")
    @Builder.Default
    private Integer theoryHours = 0;

    /**
     * 实践学时，默认值为0，记录实践教学学时数，设置范围0-1000
     */
    @Min(value = 0, message = "实践学时不能小于0")
    @Max(value = 1000, message = "实践学时不能大于1000")
    @Column(name = "practice_hours")
    @Builder.Default
    private Integer practiceHours = 0;

    /**
     * 实验学时，默认值为0，记录实验教学学时数，设置范围0-1000
     */
    @Min(value = 0, message = "实验学时不能小于0")
    @Max(value = 1000, message = "实验学时不能大于1000")
    @Column(name = "experiment_hours")
    @Builder.Default
    private Integer experimentHours = 0;

    /**
     * 实习学时，默认值为0，记录实习教学学时数，设置范围0-1000
     */
    @Min(value = 0, message = "实习学时不能小于0")
    @Max(value = 1000, message = "实习学时不能大于1000")
    @Column(name = "internship_hours")
    @Builder.Default
    private Integer internshipHours = 0;

    /**
     * 考核类型
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "assessment_type", nullable = false, length = 20)
    private AssessmentType assessmentType;

    /**
     * 是否启用
     */
    @Column(name = "is_enabled")
    @Builder.Default
    private Boolean isEnabled = true;

    /**
     * 归属单位ID，课程唯一的归属单位（学院或院系）
     */
    @Column(name = "unit_id")
    private Long unitId;

    /**
     * 创建时间
     */
    @Column(name = "create_time", nullable = false, updatable = false)
    private LocalDateTime createTime;

    /**
     * 计算总学时，包括理论、实践、实验和实习学时
     * @return 总学时
     */
    @Transient
    public Integer getTotalHours() {
        return (theoryHours != null ? theoryHours : 0) +
               (practiceHours != null ? practiceHours : 0) +
               (experimentHours != null ? experimentHours : 0) +
               (internshipHours != null ? internshipHours : 0);
    }
}
